package br.com.arndroid.lib.imp;

import android.content.Intent;
import br.com.arndroid.lib.imp.R;
import br.com.arndroid.lib.validation.ConstraintViolations;
import br.com.arndroid.lib.entity.EntityFormActivity;

public class EntityFormActivityImp extends EntityFormActivity {

	//Constants:
	
	public static final String TEST_TITLE_UPDATE = "TEST UPDATE";
	public static final String TEST_TITLE_NEW = "TEST NEW";
	public static final int RESULT_UNDEFINED = RESULT_FIRST_USER;
	public static final int RESULT_VALID = RESULT_FIRST_USER + 1;
	public static final int RESULT_INVALID = RESULT_FIRST_USER + 2;
	public static final int CONFIGURATION_UNDEFINED = -1;
	public static final int CONFIGURATION_NEW_VALNO = 0;
	public static final int CONFIGURATION_NEW_VALOK_PERSISTEDNO = 1;
	public static final int CONFIGURATION_NEW_VALOK_PERSISTEDYES = 2;
	public static final int CONFIGURATION_UPDATE_VALNO = 3;
	public static final int CONFIGURATION_UPDATE_VALOK_PERSISTEDNO = 4;
	public static final int CONFIGURATION_UPDATE_VALOK_PERSISTEDYES = 5;
	public static final String ERROR_MESSAGE = "Error message for config: ";
	public static final String ERROR_MESSAGE_FORMATTED_TOKEN = " [Formatted]";
	
	//Fields:
	
	//Actual test configuration:
	private static int mConfigID = CONFIGURATION_UNDEFINED;
	//Last msg shown for tests purposes:
	String mLastMessageShown = "";
	//Last violation, result code and intent for tests purposes:
	ConstraintViolations mLastViolations = null;
	Intent mLastResultIntent = null;
	int mLastResultCode = RESULT_UNDEFINED;	
	//Result of last validation:
	int mLastResultValidation = RESULT_UNDEFINED;
	
	//Public methods:

	public static void setInternalConfiguration(int configID) {
		mConfigID = configID;
	}
	
	@Override
	public void performPositiveAction() {
		super.performPositiveAction();
	}
	
	@Override
	public void performNegativeAction() {
		super.performNegativeAction();
	}
    
	public String getLastMessageShown() {
		return mLastMessageShown;
	}
	
	@Override
	public long getEntityID() {
		return super.getEntityID();
	}
	
	public int getLastResultCode() {
		return mLastResultCode;
	}
	
	public Intent getLastResultIntent() {
		return mLastResultIntent;
	}
	
	public int getLastResultValidation() {
		return mLastResultValidation;
	}

	//Requireds overrides:

	@Override
	public void onBindUI() {
		//For this test nothing necessary...
	}

	@Override
	public int onAcquireLayoutResID() {
		return R.layout.main;
	}

	@Override
	public int onAcquireNegativeButtonResID() {
		return R.id.btn2;
	}

	@Override
	public int onAcquirePositiveButtonResID() {
		return R.id.btn1;
	}

	@Override
	public void onInitUI(String currentAction) {
		//For this test nothing necessary...
	}

	@Override
	public long onPersistUI(String currentAction) {
		switch (mConfigID) {
		case CONFIGURATION_NEW_VALNO:
			//Not validatable, if here internal error ocurred:
			throw new IllegalStateException("Inside persisteUI(String) whith no validatable configuration");
		case CONFIGURATION_NEW_VALOK_PERSISTEDNO:
			//Validatable but not persistable, if here internal error ocurred:
			throw new IllegalStateException("Inside persisteUI(String) whith no persistable configuration");
		case CONFIGURATION_NEW_VALOK_PERSISTEDYES:
			//Validatable and persistable, return mock id:
			return CONFIGURATION_NEW_VALOK_PERSISTEDYES;
		case CONFIGURATION_UPDATE_VALNO:
			//Not validatable, if here internal error ocurred:
			throw new IllegalStateException("Inside persisteUI(String) whith no validatable configuration");
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDNO:
			//Validatable but not persistable, if here internal error ocurred:
			throw new IllegalStateException("Inside persisteUI(String) whith no persistable configuration");
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDYES:
			//Validatable and persistable, return mock id:
			return CONFIGURATION_UPDATE_VALOK_PERSISTEDYES;
		default:
			throw new IllegalStateException("Invalid mConfigID");
		}
	}

	@Override
	public ConstraintViolations onValidateUI(String currentAction) {
		switch (mConfigID) {
		case CONFIGURATION_NEW_VALNO:
			setNotValidatedVariables();
			break;
		case CONFIGURATION_NEW_VALOK_PERSISTEDNO:			
		case CONFIGURATION_NEW_VALOK_PERSISTEDYES:
			setValidatedVariables();
			break;
		case CONFIGURATION_UPDATE_VALNO:
			setNotValidatedVariables();
			break;
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDNO:
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDYES:
			setValidatedVariables();
			break;
		default:
			throw new IllegalStateException("Invalid mConfigID");
		}
		return mLastViolations;
	}

	private void setValidatedVariables() {
		mLastViolations = null;
		mLastResultValidation = RESULT_VALID;
	}

	private void setNotValidatedVariables() {
		mLastViolations = new ConstraintViolations();
		mLastViolations.addViolation(ERROR_MESSAGE + mConfigID);
		mLastResultValidation = RESULT_INVALID;
		mLastResultCode = RESULT_UNDEFINED;
		mLastResultIntent = null;
	}
	
	@Override
	public boolean isPersistable(String currentAction) {
		switch (mConfigID) {
		case CONFIGURATION_NEW_VALNO:
			//Not validatable, if here internal error ocurred:
			throw new IllegalStateException("Inside isPersistable(String) whith no validatable configuration");
		case CONFIGURATION_NEW_VALOK_PERSISTEDNO:
			return false;
		case CONFIGURATION_NEW_VALOK_PERSISTEDYES:
			return true;
		case CONFIGURATION_UPDATE_VALNO:
			//Not validatable, if here internal error ocurred:
			throw new IllegalStateException("Inside isPersistable(String) whith no validatable configuration");
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDNO:
			return false;
		case CONFIGURATION_UPDATE_VALOK_PERSISTEDYES:
			return true;
		default:
			throw new IllegalStateException("Invalid mConfigID");
		}
	}
	
	@Override
	public void onFinish(int resultCode, Intent resultIntent) {
		mLastResultCode = resultCode;
		mLastResultIntent = resultIntent;
	}

	@Override
	public void showErrorMessage(ConstraintViolations violations) {
		mLastMessageShown = violations == null ? "" : formatErrorMessage(violations); 
	}
	
	@Override
	public String onTranslateErrorMessage(String errorMessage) {
		return errorMessage + ERROR_MESSAGE_FORMATTED_TOKEN;
	}
	
	@Override
	public String onAcquireOperationTitle(String currentAction) {
		return currentAction.equals(ENTITY_ACTION_NEW) ? TEST_TITLE_NEW : TEST_TITLE_UPDATE;
	}

	@Override
	public String onAcquireValidationErrorTitle() {
		return getResources().getString(R.string.validation_error_title);
	}

	@Override
	public String onAcquireValidationErrorMessagePrefix() {
		return "";
	}
}
